// ==UserScript==
// @name BrowserShield: Anti fingerprinters
// @author nokoru (aka satoi)
// @homepageURL https://notabug.org/nokoru/browser-shield
// @date 2019-09-26
// @version 1.1.6
// @updateURL https://notabug.org/nokoru/browser-shield/raw/master/browser-shield.user.js
// @description This script fakes some browser data to enhance your privacy.
// @namespace browserShield
// @include *
// @run-at document-start
// @copyright 2019+, nokoru (https://nokoru.neocities.org/)
// @license unlicense; https://notabug.org/nokoru/browser-shield/raw/master/license.txt
// ==/UserScript==

//experimental: script priority trick taken from https://stackoverflow.com/questions/4978736/how-to-run-greasemonkey-script-before-the-page-content-is-displayed, credit to Jonas Äppelgran! thank you! :3
//"priority" trick is supposed to load this script before any other, so nothing can read navigator object before BrowserShield.
var bsStart = (new Date()).getTime();
var bsInterval = setInterval(browserShield, 50);

//BrowserShield function
function browserShield() {
  //stop executing this function either when page is ready or 20 seconds have past since bsInterval started.
  if (document.readyState == "complete" || (new Date()).getTime() - bsStart >= 20000) {
      clearInterval(bsInterval);
      return;
  }
  
  /* BrowserShield's anti-fingerprinting default settings:
   * Default browser: Google Chrome
   * Default OS: Windows 10
   * Default number of cores: randomized every time a page is reloaded
   * Default browser's language: English ("en-US")
   * Default screen resolution: 1366x768
   */

  //** SPOOF SCREEN PROPERTIES AND DIMENSIONS **
  /* Spoof screen propierties.
   * Most popular dimensions: (1) 1366x768 and (2) 1920x1080
   */
  screen = {
    width: 1366,
    height: 768,
    availWidth: 1366,
    availHeight: 768,
    colorDepth: 24,
    pixelDepth: 24,
  };
  
  //*** SPOOF BROWSER PROPERTIES ***

  /* Spoof browser's language (you can change this by modifying the "return <language>;"
   * If you aren't an english speaker, you can change this preference, however, keep in mind that revealing websites your native language can be a used as a method to track you.
   * Browser languages are defined by the ISO 639-1 codes (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). Aditionally, SOME languages support country codes defined by the ISO 3166-1 alpha-2 codes (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
   * Example: es-AR (Argentinian Spanish).
   */
  Object.defineProperty(navigator,"language", {
    get: function () { return "en-US"; },
    set: function (a) {},
    configurable: false
  });
  /* User agent switcher (DOES NOT SPOOF THE HTTP HEADER, YET!)
   * Be careful! User agents are very specific strings. List of most popular user agents: http://www.browser-info.net/useragents
   */
  Object.defineProperty(navigator, "userAgent", {
    get: function(){ return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"; },
    set: function(a) {},
    configurable: false
  });
  /* Vendor injector
   * Either "Google Inc." (in Chrome), "Apple Computer, Inc.", or (in Firefox) the empty string.
   */
  Object.defineProperty(navigator,"vendor", {
    get: function () { return "Google Inc."; },
    set: function (a) {},
    configurable: false
  });
  /* App version injector
   */
  Object.defineProperty(navigator,"appVersion", {
    get: function () { return "5.0 (Windows)"; },
    set: function (a) {},
    configurable: false
  });
  
  //** SPOOF DOCUMENT PROPERTIES **
     
  /* Clear referrer string, I recommend leave it blank. (DOES NOT SPOOF THE HTTP HEADER, YET!)
   * document.referrer is typically used to get your previously visited page.
   */ 
  Object.defineProperty(document, "referrer", {
    get: function(){ return ""; },
    set: function(a) {},
    configurable: false
  });
  
  //** SPOOF OS/COMPUTER PROPERTIES **
    
  /* Spoof platform (OS)
   * Used to get your computer's operating system.
   */
  Object.defineProperty(navigator,"platform", {
    get: function () { return "Win32"; },
    set: function (a) {},
    configurable: false
  });
  /* Spoof oscpu
   * Only Firefox supports this property, any other browser will return "undefined".
   * https://developer.mozilla.org/en-US/docs/Web/API/Navigator/oscpu
   */
  Object.defineProperty(navigator,"oscpu", {
    get: function () { return undefined; },
    set: function (a) {},
    configurable: false
  });
  /* Spoof hardwareConcurrency (CPU cores)
   * hardware concurrency = number of CPU cores (by default, this information is randomized every time a page is reloaded)
   */
  var cores = [2,4,8];
  Object.defineProperty(navigator,"hardwareConcurrency", {
    get: function () { return cores[Math.floor(Math.random() * cores.length)]; },
    set: function (a) {},
    configurable: false
  });
  
};


